﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Summerset.Isbndb.Books
{

    /// <summary>
    /// Contains all valid arguments accepted by the books collection.
    /// </summary>
    public static class BookArgs
    {

        /// <summary>
        /// Gets the valid index arguments for a BooksRequest.
        /// </summary>
        public static string[] GetValidIndexArguments()
        {

            return typeof(Arguments)
                .GetFields(BindingFlags.Public | BindingFlags.Static)
                .Select(fi => fi.GetRawConstantValue().ToString())
                .ToArray();

        }

        /// <summary>
        /// Gets the additional result fields that can be requested from the books collection.
        /// </summary>        
        public static string[] GetValidResultArguments()
        {

            return typeof(Results)
                .GetFields(BindingFlags.Public | BindingFlags.Static)
                .Select(fi => fi.GetRawConstantValue().ToString())
                .ToArray();

        }

        /// <summary>
        /// This class contains all the supported indexes of the Books collection.
        /// </summary>
        public static class Arguments
        {

            /// <summary>
            /// Search on ISBN, value is set the ISBN you are interested in.  Returns at most one match.
            /// </summary>
            /// <remarks>
            /// The returned results subset consists of zero or at most one member for this search type, ISBN records are unique in the database.
            /// </remarks>
            public const string isbn = "isbn";

            /// <summary>
            /// Keywords search on book title, long title, and latin-ized title for unicode titles
            /// </summary>
            /// <remarks>
            /// The search follows the same rules and syntax as the search on the website itself -- you can group words together using double quotes, 
            /// all non-ignored words must be present in the results.
            /// </remarks>
            public const string title = "title";

            /// <summary>
            /// Search index that combines titles, authors, and publisher name
            /// </summary>
            /// <remarks>
            /// This helps to answer queries "Title by John Doe" that many seem to type when searching for a book. 
            /// Another possibility is searching for a book with a generic title and qualifying it by author or publisher as 
            /// in the example above -- looking for O'Reilly's "hacks" series
            /// </remarks>
            public const string combined = "combined";

            /// <summary>
            /// Search index that includes titles, authors, publisher name, summary, notes, awards information, etc -- 
            /// practically every bit of textual information ISBNdb.com has about books
            /// </summary>
            /// <remarks>
            /// This helps to find books where some phrase or keywords are mentioned in other textual fields. 
            /// The search above, for instance, comes up with a Rex Stout book that only mentions this address in its annotation.
            /// </remarks>
            public const string full = "full";

            /// <summary>
            /// Retrieving book data by ISBNdb.com's book ID. Returns at most one match.
            /// </summary>       
            public const string book_id = "book_id";

            /// <summary>
            /// Retrieves a list of books by the given author, editor, etc. 
            /// The ID of the person needs to be first retrieved by searching on 'persons' collection.
            /// </summary>
            public const string person_id = "person_id";

            /// <summary>
            /// Retrieves a list of books by the given publisher ID that can be retrieved by searching on the 'publishers' 
            /// collection or by a reference from another book's data.
            /// </summary>
            public const string publisher_id = "publisher_id";

            /// <summary>
            /// Retrieves a list of books on the given subject. The subject ID can be looked up by searching in 'subjects' 
            /// collection or by a reference from another book.
            /// </summary>
            public const string subject_id = "subject_id";

            /// <summary>
            /// Retrieves a list of books by the given Dewey Decimal Classification number.
            /// </summary>
            public const string dewey_decimal = "dewey_decimal";

            /// <summary>
            /// Retrieves a list of books by the given Library of Congress Classification number.
            /// </summary>
            public const string lcc_number = "lcc_number";

        }

        /// <summary>
        /// In addition to common 'results' blocks the books collection adds some that are book specific. 
        /// The syntax remains the same -- comma separated values in the 'results' argument.
        /// </summary>
        public static class Results
        {

            /// <summary>
            /// Show more details about books -- LCC and Dewey decimal classification, release data, etc
            /// </summary>         
            /// <remarks>
            /// Attributes in the Details tag have the following meaning:
            /// dewey_decimal - Dewey Decimal Classification number for the book as received from libraries.
            /// dewey_decimal_normalized - Normalized Dewey Decimal Classification number. Unfortunately, in many cases the number as received has inconsistent characters or formatting. This attribute represents our best effort at normalizing it.
            /// lcc_number - Library of Congress Classification number.
            /// language - Language code for the book.
            /// physical_description_text - free form text describing physical characteristics of the book.
            /// edition_info - free form text describing a particular edition of some text represented by this book.
            /// change_time - timestamp of the last change to the book's data
            /// price_time - timestamp of the last prices update for the book. You can use 'prices' results code to retrieve actual price records.
            /// </remarks>
            public const string details = "details";

            /// <summary>
            /// Show textual blocks for the book -- notes, summary, awards information, related URLs, etc.
            /// </summary>
            /// <remarks>
            /// Text values returned are free-form and can be relatively large -- up to several kb.
            /// </remarks>
            public const string texts = "texts";

            /// <summary>
            /// Show current prices for the found books.
            /// </summary>
            public const string prices = "prices";

            /// <summary>
            /// The same as 'prices', but the results are not limited to most current prices -- 
            /// including full set of historic prices known for the books. 
            /// Note that amount of historic records depends on book popularity and on how frequently prices change for a given book -- 
            /// a new record is stored only if it is different from the previous one, without strong correspondence to specific points in time.
            /// </summary>            
            public const string pricehistory = "pricehistory";

            /// <summary>
            /// This argument tells ISBNdb.com server to return a list of subjects for each book found.
            /// </summary>
            /// <remarks>
            /// Additional information on subjects (subject composition, parts, etc) can be found by queries on 'subjects' data collection. 
            /// You can also search for additional books on these subjects by using 'subject_id' index described above in this section.
            /// </remarks>
            public const string subjects = "subjects";

            /// <summary>
            /// This argument tells ISBNdb.com server to return a list of URLs to the book's MARC records if it has any.
            /// </summary>
            public const string marc = "marc";

            /// <summary>
            /// This argument tells ISBNdb.com server to return a list of authors, editors, etc for each book found.
            /// </summary>
            /// <remarks>
            /// Additional information on authors can be found by queries on 'authors' data collection.
            /// </remarks>
            public const string authors = "authors";

        }
    }
}
